package java_option.player.javacv.core;

import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.FrameGrabber.Exception;

import java_option.player.javacv.ext.VideoDurationUpdate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 用于从视频文件中获取视频Frame
 * 
 * @author java红了 <br/>
 *         2020-9-2719:38:41
 */
public class FrameVideoGrabberThread extends Thread {

	private static final Logger logger = LoggerFactory.getLogger(FrameVideoGrabberThread.class);

	private String tag = FrameVideoGrabberThread.class.getSimpleName();

	private static FrameVideoGrabberThread instance;

	private FFmpegFrameGrabber frameGrabber;

	/**
	 * true 运行, false wait null 停止
	 */
	private Boolean isRunning = false;
	/**
	 * grab视频是否结束 true结束
	 */
	private boolean isGrabEnd = false;

	private long videoIndex;

	private FrameVideoGrabberThread() {

	}

	public static FrameVideoGrabberThread getInstance() {
		synchronized (FrameVideoGrabberThread.class) {
			if (instance == null) {
				instance = new FrameVideoGrabberThread();
			}
		}
		return instance;
	}

	public void startGrab(FFmpegFrameGrabber frameGrabber) {
		this.frameGrabber = frameGrabber;
		// 注意调用 super的start方法, 因为当前类已经重写了start
		try {
			this.frameGrabber.start();
//			frameGrabber.setTimestamp(1);// 从1开始
			// 设置视频总时长 -- 单位秒
			long totalDurationSec = this.frameGrabber.getLengthInTime() / 1000000;
			VideoDurationUpdate.getInstance().setTotalDuration(totalDurationSec);
		} catch (Exception e) {
			e.printStackTrace();
		}
		// 注意 在线程start之前设置
		this.isRunning = true;
		super.start();
	}

	public void waitGrab() {
		synchronized (instance) {
			try {
				instance.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	public void notifyGrab() {
		synchronized (instance) {
			instance.notify();
		}
	}

	@Override
	public void start() {
		throw new RuntimeException("请调用 startGrab(FFmpegFrameGrabber)方法 ");
	}

	@Override
	public void run() {
		while (true) {
			try {
				if (isRunning == null) {
					break;
				}
				if (isRunning == false) {
					this.waitGrab();
				}
				Frame frame = frameGrabber.grabFrame();
				if (frame == null) {
					this.isGrabEnd = true;
					logger.debug("frame == null 视频结束");
					// wait 不结束、保证以后滑动slider还可以继续播放
					this.waitGrab();
					continue;
				}
				logger.debug("grab video " + frame.image);
				this.isGrabEnd = false;
				if (frame.image != null) {
					videoIndex++;
					boolean isContinue = FrameFIFO.getInstance().putVideo(frame, videoIndex,frame.timestamp);
					if (isContinue == false) {
						this.waitGrab();
					}
				} else if (frame.samples != null) {
					continue;
				} else {
					// logger.debug("Frame vide Grabber Thread 出现异常 ");
					continue;
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

		}
	}

	/**
	 * 设置播放进度
	 * 
	 * @param timestamp
	 */
	public void setTimestamp(long timestamp) {
		try {
			this.frameGrabber.setTimestamp(timestamp);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void setRunning(Boolean isRunning) {
		this.isRunning = isRunning;
		if (isRunning != null && isRunning) {
			notifyGrab();
		}
		if (this.isRunning == null) {
			instance = null;
		}
	}

	public boolean isGrabEnd() {
		return this.isGrabEnd;
	}
}
